package ttsolver.util;

import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.HashMap;
import java.util.List;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;

import com.sun.org.apache.xerces.internal.impl.dv.xs.DecimalDV;

import ttsolver.input.Movement;
import ttsolver.input.Node;
import ttsolver.input.Train;
import ttsolver.output.ProblemSolution;

public class XMLUtil {
	public static void saveSolutionToXML(ProblemSolution problemSolution,
			String nomeArquivo) throws ParserConfigurationException,
			IOException, TransformerException {
		DocumentBuilderFactory docFactory = DocumentBuilderFactory
				.newInstance();
		DocumentBuilder docBuilder = docFactory.newDocumentBuilder();

		Node inNode;
		Node outNode;
		double inTime;
		double outTime;
		DecimalFormat decForm = new DecimalFormat("0,000");

		// root elements
		Document doc = docBuilder.newDocument();
		Element rootElement = doc.createElement("solution");
		rootElement.setAttribute("territory", problemSolution.getName());
		doc.appendChild(rootElement);

		// trains
		Element trains = doc.createElement("trains");
		rootElement.appendChild(trains);

		List<Train> trainList = problemSolution.getTrainList();
		for (Train train : trainList) {
			// train
			Element trainTag = doc.createElement("train");
			trainTag.setAttribute("id", train.getHeader());
			trains.appendChild(trainTag);

			// movements
			Element movements = doc.createElement("movements");
			trainTag.appendChild(movements);

			HashMap<Long, Movement> movList = problemSolution.getMovList().get(
					train.getId());
			Long originNode = train.getOriginNodeId();
			Long destinationNode = train.getDestinationNodeId();

			Long nextNode = originNode;
			do {
				Movement mov = movList.get(nextNode);

				inNode = mov.getInNode();
				outNode = mov.getOutNode();
				inTime = mov.getInTime();
				outTime = mov.getOutTime();

				// mov
				Element movement = doc.createElement("movement");
				String arc = "(" + inNode.getId() + "," + outNode.getId() + ")";
				movement.setAttribute("arc", arc);
				movement.setAttribute("entry",
						String.valueOf(decForm.format(inTime)));
				if (outTime <= InstantesUtil.getMaxSecond())
					movement.setAttribute("exit",
							String.valueOf(decForm.format(outTime)));
				movements.appendChild(movement);

				nextNode = outNode.getId();
			} while (nextNode != destinationNode);

			// destination entr
			if (outTime <= InstantesUtil.getMaxSecond()) {
				Element destination = doc.createElement("destination");
				destination.setAttribute("entry",
						String.valueOf(decForm.format(outTime)));
				movements.appendChild(destination);
			}
		}

		// Write XML
		TransformerFactory transformerFactory = TransformerFactory
				.newInstance();
		Transformer transformer = transformerFactory.newTransformer();
		transformer.setOutputProperty("indent", "yes");
		transformer.setOutputProperty(
				"{http://xml.apache.org/xalan}indent-amount", "3");
		transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");

		DOMSource source = new DOMSource(doc);

		// Date now = Calendar.getInstance().getTime();
		File myFile1 = new File(nomeArquivo);
		myFile1.createNewFile();

		StreamResult result1 = new StreamResult(myFile1);

		transformer.transform(source, result1);
	}
}
